package com.motong.gongdan.controller.system;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.config.CustomCellWriteHandler;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.LoginException;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.constant.CommonConstant;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.*;
import com.motong.gongdan.util.page.PageInfo;
import com.motong.gongdan.vo.ExcelModel.*;
import com.motong.gongdan.vo.resp.NameVo;
import com.motong.gongdan.vo.resp.WagesMatchRuleResp;
import com.motong.gongdan.vo.system.CustomField.ColumnsConfigure;
import com.motong.gongdan.vo.system.CustomField.SearchConditionModel;
import com.motong.gongdan.vo.system.common.query.GetSearchCacheQuery;
import com.motong.gongdan.vo.system.common.query.IdValueQuery;
import com.motong.gongdan.vo.system.otherVo.*;
import com.motong.gongdan.vo.system.processSop.CollectionDataVo;
import com.motong.gongdan.vo.system.processSop.ProcessSopZoneVo;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author:fff
 * @time:2022/2/23
 */
@Api(value = "基础数据", tags = {"基础数据"})
@RestController
@Slf4j
@RequestMapping(value = "/sys/base/")
public class BaseController {
    @Value("${qRFilePrefix}")
    private String qRFilePrefix;

    @Value("${excel.templatePath}")
    private String excelTemplatePath;

    @Value("${excel.printTemplatePath}")
    private String printTemplatePath;

    @Resource
    BadProductService badProductService;
    @Resource
    ProductService productService;
    @Resource
    UserService userService;
    @Resource
    ProcessRouteService processRouteService;
    @Resource
    UnitService unitService;
    @Resource
    ProcessesService processesService;
    @Resource
    DepartmentsService departmentsService;
    @Resource
    WagesService wagesService;
    @Resource
    WorkOrderService workOrderService;
    @Resource
    MissionService missionService;
    @Resource
    CustomFieldService customFieldService;
    @Resource
    CustomNumberService customNumberService;
    @Resource
    DictService dictService;
    @Resource
    ProcessSopService processSopService;
    @Resource
    MatchingRuleService matchingRuleService;
    @Resource
    DimensionCombinationService dimensionCombinationService;
    @Resource
    ScreenPlanService screenPlanService;
    @Resource
    private WorkReportService workReportService;
    @Resource
    MongoTemplate mongoTemplate;
    @Resource
    UserMenuService userMenuService;
    @Resource
    private FormTableDetailService formTableDetailService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private BomInfoService bomInfoService;


    @UserLoginToken
    @ApiOperation(value = "产品列表")
    @RequestMapping(value = "product_list", method = RequestMethod.POST)
    public ResponseData<?> productList(@RequestBody ProductListVo vo) {
        List<Integer> mongoList = new ArrayList<>();
        if (vo.getCustomFieldSearch() != null && !vo.getCustomFieldSearch().isEmpty()) {
            List<Object> list = MongoUtils.getSearchResult(vo.getCustomFieldSearch(), "product", customFieldService, mongoTemplate);
            if (!CollectionUtils.isEmpty(list)) {
                list.forEach(l -> {
                    Product product = new Product();
                    product = JSONObject.parseObject(JSON.toJSONString(l)).toJavaObject(Product.class);
                    mongoList.add(product.getId());
                });
            } else {
                mongoList.add(0);
            }
        }
        synchronized (BaseController.class) {
            Page<Product> data = productService.page(new Page<Product>(vo.getPage(), vo.getLimit()), new QueryWrapper<Product>()
                    .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode())
                    .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                    .like(StringUtil.isNotBlank(vo.getSpecification()), "specification", vo.getSpecification())
                    .eq(vo.getAttribute() != null, "attribute", vo.getAttribute())
                    .eq("del_flag", 0).in(!CollectionUtils.isEmpty(mongoList), "id", mongoList));
            if (data != null && !CollectionUtils.isEmpty(data.getRecords())) {
                List<Product> updateProducts = new ArrayList<>();
                data.getRecords().forEach(r -> {
                    if (r.getCreateId() != null) {
                        User u = userService.getById(r.getCreateId());
                        r.setCreateName(u.getName());
                    }
                    if (StringUtil.isNotBlank(r.getOther())) {
                        r.setCustomFieldVos(customFieldService.handleCustomFieldForList(r.getOther()));
                    }
                    if (StringUtils.hasLength(r.getQr())) {
                        r.setQr(r.getQr().replace("/service", ""));
                    }
                    ProductDataHandle(r);
                    int attribute = Optional.ofNullable(r.getAttribute()).orElse(0);
                    r.setAttributeName(attribute == 0 ? "自制" : (attribute == 1 ? "外购" : "委外"));
                });
//                if (!CollectionUtils.isEmpty(updateProducts)) {
//                    productService.updateBatchById(updateProducts);
//                }
            }
            return ResponseData.success(data);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "产品新建编辑删除")
    @RequestMapping(value = "product_handle", method = RequestMethod.POST)
    public ResponseData<?> productHandle(@RequestBody Product vo) {
        boolean isUpdate = Objects.nonNull(vo.getId());
        if (vo.getId() != null) {
            vo.setUpdateTime(new Date());
        } else if (StringUtil.isBlank(vo.getCode())) {
            String code = customNumberService.generator(7);
            if (code.equals("fail")) {
                return ResponseData.fail(500, "流水号已用完，请手动输入");
            }
            vo.setCode(code);
        }
        if (vo.getId() == null) {
            if (productService.count(new LambdaQueryWrapper<Product>().eq(Product::getCode, vo.getCode())) > 0) {
                return ResponseData.fail(500, "产品编号已存在");
            }
            vo.setCreateId(LoginUtil.getLoginUserId());
        }
        if (vo.getDelFlag() != null && vo.getDelFlag() == 1 && vo.getId() != null) {
            List<WorkOrder> list = workOrderService.list(new QueryWrapper<WorkOrder>().eq("product_id", vo.getId()));
            long formTableDetailCount = formTableDetailService.count(new LambdaQueryWrapper<FormTableDetail>().eq(FormTableDetail::getProductId, vo.getId()));
            if (!CollectionUtils.isEmpty(list) || formTableDetailCount > 0) {
                return ResponseData.fail(500, "工单产品使用中不可删除");
            }
            MongoUtils.deleteById(vo.getId(), mongoTemplate, "product");
            //删除物料清单中数据
            bomInfoService.remove(new LambdaQueryWrapper<BomInfo>().eq(BomInfo::getParentProductId, vo.getId())
                    .or().eq(BomInfo::getChildProductId, vo.getId()));
        }
        productService.saveOrUpdate(vo);
        if (!isUpdate) {
            String fileName = qRFilePrefix + System.currentTimeMillis() + ".jpg";
            QrCodeUtil.generate(String.format("productId=%d", vo.getId()), 300, 300, cn.hutool.core.io.FileUtil.file(fileName));
            vo.setQr(fileName);
        }
        if (CollectionUtils.isEmpty(vo.getCustomFieldVos())) {
            MongoUtils.deleteById(vo.getId(), mongoTemplate, "product");
            productService.updateById(vo);
        }
        Product product = productService.getById(vo.getId());
        if (!CollectionUtils.isEmpty(vo.getCustomFieldVos())) {
            product.setOther(customFieldService.handleObjectCreateOrEdit(vo.getCustomFieldVos()).toJSONString());
            productService.saveOrUpdate(product);
            Product mongoProduct = new Product();
            mongoProduct.setId(product.getId());
            mongoProduct.setCode(product.getCode());
            mongoProduct.setCustomFieldMess(JSONArray.parseArray(product.getOther()));
            mongoTemplate.save(mongoProduct);
        }
        return ResponseData.success(product);
    }

    @UserLoginToken
    @ApiOperation(value = "产品导入")
    @RequestMapping(value = "product_import", method = RequestMethod.POST)
    public ResponseData<?> productImport(MultipartFile file, Integer type) throws IOException {
        productService.handleImport(file, type);
        return ResponseData.success("请查看导入日志");
    }

    @UserLoginToken
    @ApiOperation(value = "导出")
    @RequestMapping(value = "export_product", method = RequestMethod.GET)
    public void exportProduct(HttpServletResponse response) throws IOException {
        List<ProductImportModel> exportList = new ArrayList<>();
        List<Product> list = productService.list(new QueryWrapper<Product>().eq("del_flag", 0));
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(p -> {
                ProductImportModel pim = new ProductImportModel();
                SpringUtil.copyPropertiesIgnoreNull(p, pim);
                pim.setName(p.getName());
                pim.setSpecification(p.getSpecification());
                Unit unit = unitService.getById(p.getUnitId());
                pim.setUnit(unit.getName());
                if (p.getProcessRouteId() != null) {
                    ProcessRoute processRoute = processRouteService.getById(p.getProcessRouteId());
                    pim.setProcessRoute(processRoute.getName());
                }
                exportList.add(pim);
            });
            String fileName = "exportExcel" + System.currentTimeMillis() + ".xlsx";
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            EasyExcel.write(response.getOutputStream()).sheet("产品导出数据").head(ProductImportModel.class).doWrite(exportList);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "单位操作创建编辑")
    @RequestMapping(value = "unit_handle", method = RequestMethod.POST)
    public ResponseData<?> unitHandle(@RequestBody Unit vo) {
        Unit unit = unitService.getOne(new QueryWrapper<Unit>().eq("name", vo.getName()));
        if (unit != null && vo.getId() == null) {
            return ResponseData.fail(500, "名称重复");
        }
        unitService.saveOrUpdate(vo);
        return ResponseData.success(vo);
    }

    @UserLoginToken
    @ApiOperation(value = "删除单位")
    @RequestMapping(value = "unit_del", method = RequestMethod.POST)
    public ResponseData<?> unitDel(@RequestBody IdVo vo) {
        List<Product> products = productService.list(new QueryWrapper<Product>().eq("unit_id", vo.getId()));
        if (!CollectionUtils.isEmpty(products)) {
            return ResponseData.success("当前单位有产品在用");
        }
        unitService.removeById(vo.getId());
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "单位列表")
    @RequestMapping(value = "unit_list", method = RequestMethod.POST)
    public ResponseData<?> unitList(@RequestBody UnitListVo vo) {
        Page<Unit> data = unitService.page(new Page<Unit>(vo.getPage(), vo.getLimit()), new QueryWrapper<Unit>()
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .like(StringUtil.isNotBlank(vo.getComment()), "comment", vo.getComment()));
        return ResponseData.success(data);
    }

    @UserLoginToken
    @ApiOperation(value = "不良品项列表")
    @RequestMapping(value = "bad_product_list", method = RequestMethod.POST)
    public ResponseData<?> badProductList(@RequestBody NormalVo vo) {
        Page<BadProduct> page = badProductService.page(new Page<BadProduct>(vo.getPage(), vo.getLimit()),
                new QueryWrapper<BadProduct>()
                        .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                        .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode()));
        return ResponseData.success(page);
    }

    @UserLoginToken
    @ApiOperation(value = "不良品项添加编辑")
    @RequestMapping(value = "bad_product_handle", method = RequestMethod.POST)
    public ResponseData<?> badProductHandle(@RequestBody BadProduct vo) {
        if (vo.getId() != null) {
            badProductService.updateById(vo);
        } else {
            if (StringUtil.isBlank(vo.getCode())) {
                String code = customNumberService.generator(8);
                if (code.equals("fail")) {
                    return ResponseData.fail(500, "流水号已用完，请手动输入");
                }
                vo.setCode(code);
            } else {
                BadProduct badProduct = badProductService.getOne(new QueryWrapper<BadProduct>().eq("code", vo.getCode()));
                if (badProduct != null) {
                    return ResponseData.fail(500, "不良品编号重复");
                }
            }
            vo.setCreateTime(new Date());
            badProductService.save(vo);
        }
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "不良品项删除")
    @RequestMapping(value = "bad_product_del", method = RequestMethod.POST)
    public ResponseData<?> badProductDel(@RequestBody IdVo vo) {
        BadProduct badProduct = badProductService.getById(vo.getId());
        if (badProduct != null) {
            List<Processes> processesList = processesService.getBaseMapper().getProcessesByBP(badProduct.getId().toString());
            if (!CollectionUtils.isEmpty(processesList)) {
                return ResponseData.fail(500, "已在使用不良品项");
            }
            badProductService.removeById(badProduct.getId());
            return ResponseData.success("success");
        }
        return ResponseData.fail(500, "失败");
    }


    @UserLoginToken
    @ApiOperation(value = "工序列表")
    @RequestMapping(value = "process_list", method = RequestMethod.POST)
    public ResponseData<?> processList(@RequestBody NormalVo vo) {
        List<Integer> list = new ArrayList<>();
        if (vo.getCustomFieldSearch() != null && !vo.getCustomFieldSearch().isEmpty()) {
            List<Object> objects = MongoUtils.getSearchResult(vo.getCustomFieldSearch(), "processes", customFieldService, mongoTemplate);
            if (!CollectionUtils.isEmpty(objects)) {
                objects.forEach(l -> {
                    Processes processes = JSONObject.parseObject(JSON.toJSONString(l)).toJavaObject(Processes.class);
                    list.add(processes.getId());
                });
            } else {
                list.add(0);
            }
        }
        synchronized (Processes.class) {
            IPage<Processes> page = processesService.page(new Page<>(vo.getPage(), vo.getLimit()), new QueryWrapper<Processes>()
                    .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode())
                    .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName()).in(!CollectionUtils
                            .isEmpty(list), "id", list));
            if (!CollectionUtils.isEmpty(page.getRecords())) {
                List<Processes> updateProcesses = new ArrayList<>();
                page.getRecords().forEach(d -> {
                    ProcessesDataHandle(d, badProductService, userService);
                    if (StringUtil.isNotBlank(d.getOther())) {
                        d.setCustomFieldVos(customFieldService.handleCustomFieldForList(d.getOther()));
                    }
                    if (StringUtil.isNotBlank(d.getCollectionData())) {
                        d.setVos(JSONArray.parseArray(d.getCollectionData()).toJavaList(CollectionDataVo.class));
                    }
                    if (!StringUtils.hasLength(d.getQr())) {
                        String fileName = qRFilePrefix + System.currentTimeMillis() + ".jpg";
                        QrCodeUtil.generate(String.format("processId=%d", d.getId()), 300, 300, cn.hutool.core.io.FileUtil.file(fileName));
                        d.setQr(fileName);
                        updateProcesses.add(d);
                    }
                    if (StringUtils.hasLength(d.getQr())) {
                        d.setQr(d.getQr().replace("/service", ""));
                    }
                });
                if (!CollectionUtils.isEmpty(updateProcesses)) {
                    processesService.updateBatchById(updateProcesses);
                }
            }
            return ResponseData.success(page);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "工序编辑/新增")
    @RequestMapping(value = "edit_add", method = RequestMethod.POST)
    public ResponseData<?> editAdd(@RequestBody Processes vo) {
        ResponseData<String> responseData = processesService.getStringResponseData(vo);
        return responseData;
    }

    @UserLoginToken
    @ApiOperation(value = "工序sop模版分区内选项")
    @RequestMapping(value = "zone_option", method = RequestMethod.POST)
    public ResponseData<?> zoneOption(@RequestBody IdVo vo) {
        Processes processes = processesService.getById(vo.getId());
        List<CollectionDataVo> vos = new ArrayList<>();
        if (StringUtil.isNotBlank(processes.getCollectionData())) {
            vos = JSONArray.parseArray(processes.getCollectionData()).toJavaList(CollectionDataVo.class);
        }
        return ResponseData.success(vos);
    }


    @UserLoginToken
    @ApiOperation(value = "sop模版编辑")
    @RequestMapping(value = "sop_edit", method = RequestMethod.POST)
    public ResponseData<?> sopEdit(@RequestBody ProcessSop vo) {
        ProcessSop ps = new ProcessSop();
        if (vo.getId() == 0) {
            ps = processSopService.getOne(new LambdaQueryWrapper<ProcessSop>().orderByAsc(ProcessSop::getId).last("LIMIT 1"));
        } else {
            Processes processes = processesService.getById(vo.getId());
            ps = processSopService.getOne(new QueryWrapper<ProcessSop>().eq("process_code", processes.getCode()));
        }
        if (!CollectionUtils.isEmpty(vo.getVos())) {
            vo.getVos().forEach(i -> {
                if (!CollectionUtils.isEmpty(i.getDown())) {
                    i.getDown().forEach(d -> {
                        d.setType(Optional.ofNullable(d.getType()).orElse(""));
                        d.setValue(Optional.ofNullable(d.getValue()).orElse(""));
                    });
                }
            });
            vo.setZoneDetail(JSONUtil.toJsonStr(vo.getVos()));
        } else {
            vo.setZoneDetail("");
        }
        vo.setId(null);
        if (ps != null) {
            vo.setId(ps.getId());
        }
        processSopService.saveOrUpdate(vo);
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "sop详情 默认模版为id为0")
    @RequestMapping(value = "sop_detail", method = RequestMethod.POST)
    public ResponseData<?> sopDetail(@RequestBody IdVo vo) {
        ProcessSop ps = new ProcessSop();
//        User user = userService.getById(LoginUtil.getLoginUserId());
        if (vo.getId() == 0) {
            ps = processSopService.getOne(new LambdaQueryWrapper<ProcessSop>().orderByAsc(ProcessSop::getId).last("LIMIT 1"));
        } else {
            Processes processes = processesService.getById(vo.getId());
            ps = processSopService.getOne(new QueryWrapper<ProcessSop>().eq("process_code", processes.getCode()));
        }
        if (ps != null && StringUtil.isNotBlank(ps.getZoneDetail())) {
            ps.setVos(JSONArray.parseArray(ps.getZoneDetail()).toJavaList(ProcessSopZoneVo.class));
        } else {
            Processes processes = processesService.getById(vo.getId());
            ps = new ProcessSop();
            ps.setProcessCode(processes.getCode());
            ps.setProcessName(processes.getName());
            ps.setState(1);
            ps.setBeginZone("开始生产任务");
            ps.setEndZone("结束生产任务");
        }
        return ResponseData.success(ps);
    }

    //@UserLoginToken
    @UserLoginToken
    @ApiOperation(value = "工序导入")
    @RequestMapping(value = "process_import", method = RequestMethod.POST)
    public ResponseData<?> processImport(MultipartFile file, Integer type) throws IOException {
        processesService.handleImport(file, type);
        return ResponseData.success("请查看导入日志");
    }

    @UserLoginToken
    @ApiOperation(value = "工序导出")
    @RequestMapping(value = "process_export", method = RequestMethod.GET)
    public void processExport(HttpServletResponse response) throws IOException {
        List<ProcessesExcelVo> exportList = new ArrayList<>();
        List<Processes> dataList = processesService.list();
        if (!CollectionUtils.isEmpty(dataList)) {
            dataList.forEach(d -> {
                ProcessesExcelVo vo = new ProcessesExcelVo();
                BeanUtils.copyProperties(d, vo);
                exportList.add(vo);
            });
            String fileName = "exportExcel" + System.currentTimeMillis() + ".xlsx";
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            EasyExcel.write(response.getOutputStream()).sheet("工序导出数据").head(ProcessesExcelVo.class).doWrite(exportList);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "工序删除")
    @RequestMapping(value = "process_del", method = RequestMethod.POST)
    public ResponseData<?> processDel(@RequestBody IdVo vo) {
        if (vo.getId() != null) {
            Processes pro = processesService.getById(vo.getId());
            List<Mission> missions = missionService.list(new QueryWrapper<Mission>().eq("process_code", pro.getCode()));
            if (CollectionUtils.isEmpty(missions)) {
                processesService.removeById(vo.getId());
                MongoUtils.deleteById(vo.getId(), mongoTemplate, "processes");
                List<ProcessRoute> prList = processRouteService.list();
                if (!CollectionUtils.isEmpty(prList)) {
                    prList.forEach(pr -> {
                        if (StringUtil.isNotBlank(pr.getProcessList())) {
                            List<ProcessRoteProcessVo> list = JSONArray.parseArray(pr.getProcessList()).toJavaList(ProcessRoteProcessVo.class);
                            List<ProcessRoteProcessVo> listNew = list.stream().filter(f -> f.getId() != vo.getId()).collect(Collectors.toList());
                            if (!CollectionUtils.isEmpty(listNew)) {
                                int a = 0;
                                for (ProcessRoteProcessVo processRoteProcessVo : listNew) {
                                    processRoteProcessVo.setOrder(a);
                                    a++;
                                }
                            }
                            JSONArray ja = JSONArray.parseArray(JSON.toJSONString(listNew));
                            pr.setProcessList(ja.toJSONString());
                            processRouteService.updateById(pr);
                        }
                    });
                }
                return ResponseData.success("success");
            }
        }
        return ResponseData.fail(500, "工单正在使用,无法删除");
    }

    @UserLoginToken
    @ApiOperation(value = "工艺路线列表")
    @RequestMapping(value = "process_route_list", method = RequestMethod.POST)
    public ResponseData<?> processRouteList(@RequestBody ProcessRouteListVo vo) {
        IPage<ProcessRoute> page = processRouteService.page(new Page<>(vo.getPage(), vo.getLimit()), new QueryWrapper<ProcessRoute>()
                .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode())
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName()));
        if (!CollectionUtils.isEmpty(page.getRecords())) {
            page.getRecords().forEach(p -> {
                if (StringUtil.isNotBlank(p.getProcessList())) {
                    JSONArray jsonArray = JSON.parseArray(p.getProcessList());
                    List<ProcessRoteProcessVo> list = jsonArray.toJavaList(ProcessRoteProcessVo.class);
                    p.setList(list);
                }
            });
        }
        return ResponseData.success(page);
    }

    @UserLoginToken
    @ApiOperation(value = "工艺路线操作")
    @PostMapping("process_route_handle")
    public ResponseData<?> processRouteHandle(@RequestBody ProcessRoute vo) {
        // 工艺路线名称判重
        if (processRouteService.count(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getName, vo.getName()).ne(Objects.nonNull(vo.getId()), ProcessRoute::getId, vo.getId())) > 0) {
            return ResponseData.fail(500, "工艺路线名称不能重复");
        }

        if (vo.getId() == null) {
            if (StringUtil.isBlank(vo.getCode())) {
                String code = customNumberService.generator(10);
                if (code.equals("fail")) {
                    return ResponseData.fail(500, "流水号已用完，请手动输入");
                }
                vo.setCode(code);
            } else {
                ProcessRoute pr = processRouteService.getOne(new QueryWrapper<ProcessRoute>().eq("code", vo.getCode()));
                if (pr != null) {
                    return ResponseData.fail(500, "工艺路线编号重复");
                }
            }
        }
        if (!CollectionUtils.isEmpty(vo.getList())) {
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(vo.getList()));
            vo.setProcessList(jsonArray.toJSONString());
        } else {
            return ResponseData.fail(500, "工序列表必填");
        }
        processRouteService.saveOrUpdate(vo);
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "工艺路线删除")
    @RequestMapping(value = "process_route_del", method = RequestMethod.POST)
    public ResponseData processRouteDel(@RequestBody IdVo vo) {
        processRouteService.removeById(vo.getId());
        return ResponseData.success("success");
    }

    /**
     * processList excel中写入编号,隔开
     *
     * @param file
     * @return
     * @throws IOException
     */
    @UserLoginToken
    @ApiOperation(value = "工艺路线导入")
    @RequestMapping(value = "process_route_import", method = RequestMethod.POST)
    public ResponseData<?> processRouteImport(MultipartFile file, Integer type) throws IOException {
        String account = LoginUtil.getLoginAccount();
        EasyExcelUtils easyExcelUtils = new EasyExcelUtils(ProcessRouteImportModel.class);
        EasyExcel.read(file.getInputStream(), ProcessRouteImportModel.class, easyExcelUtils).sheet().headRowNumber(2).doRead();
        ResponseData<?> rd = easyExcelUtils.getResponseData();
        if (rd.getCode() == 500) {
            return rd;
        }
        if (type == null) {
            type = 0;
        }
        AtomicBoolean isBlank = new AtomicBoolean(true);
        Integer finalType = type;
        EasyExcel.read(file.getInputStream(), ProcessRouteImportModel.class, new PageReadListener<ProcessRouteImportModel>(dataList -> {

            isBlank.set(false);

            Map<String, Integer> dataMap = new HashMap<>();
            List<Map<String, String>> failList = new ArrayList<>();
            int a = 0;
            int b = 0;
            for (ProcessRouteImportModel d : dataList) {
                Map<String, String> failMap = new HashMap<>();
                ProcessRoute pr = new ProcessRoute();
                if (StringUtil.isNotBlank(d.getCode())) {
                    ProcessRoute prOld = processRouteService.getOne(new QueryWrapper<ProcessRoute>().eq("code", d.getCode()));
                    if (prOld != null && finalType == 1) {
                        pr = prOld;
                    } else if (prOld != null) {
                        failMap.put("失败原因", "已存在相同编号");
                        failMap.put("工艺路线编号", d.getCode());
                        failMap.put("工艺路线名称", d.getName());
                        failMap.put("工序列表", StringUtil.isNotBlank(d.getProcessList()) ? d.getProcessList() : "-");
                        failList.add(failMap);
                        b++;
                        continue;
                    }
                } else {
                    String code = customNumberService.generator(10);
                    if (code.equals("fail")) {
                        failMap.put("失败原因", "流水号已用完，请手动输入");
                        failMap.put("工艺路线编号", d.getCode());
                        failMap.put("工艺路线名称", d.getName());
                        failMap.put("工序列表", StringUtil.isNotBlank(d.getProcessList()) ? d.getProcessList() : "-");
                        failList.add(failMap);
                        b++;
                        continue;
                    }
                    d.setCode(code);
                }
                if (StringUtil.isNotBlank(d.getProcessList())) {
                    List<String> processNames = Arrays.asList(d.getProcessList().split(","));
                    List<Processes> list = processesService.list(new QueryWrapper<Processes>().in("name", processNames));
                    List<String> noExistName = new ArrayList<>();
                    if (CollectionUtils.isEmpty(list) && !CollectionUtils.isEmpty(processNames)) {
                        noExistName.addAll(processNames);
                    }
                    if (!CollectionUtils.isEmpty(list) && !CollectionUtils.isEmpty(processNames)) {
                        Set<String> existProcessesName = list.stream().map(Processes::getName).collect(Collectors.toSet());
                        processNames.forEach(i -> {
                            if (existProcessesName.add(i)) {
                                noExistName.add(i);
                            }
                        });
                        List<ProcessRoteProcessVo> voList = new ArrayList<>();
                        list.forEach(l -> {
                            ProcessRoteProcessVo vo = new ProcessRoteProcessVo();
                            vo.setName(l.getName());
                            vo.setId(l.getId());
                            vo.setRate(BigDecimal.ONE);
                            vo.setCode(l.getCode());
                            vo.setType("工序");
                            voList.add(vo);
                        });
                        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(voList));
                        pr.setProcessList(jsonArray.toJSONString());
                    }
                    if (!CollectionUtils.isEmpty(noExistName)) {
                        failMap.put("失败原因", "工序 {" + String.join(",", noExistName) + "} 不存在");
                        failMap.put("工艺路线编号", d.getCode());
                        failMap.put("工艺路线名称", d.getName());
                        failMap.put("工序列表", StringUtil.isNotBlank(d.getProcessList()) ? d.getProcessList() : "-");
                        failList.add(failMap);
                        b++;
                        continue;
                    }
                }
                pr.setCode(d.getCode());
                pr.setName(d.getName());
                boolean result = processRouteService.saveOrUpdate(pr);
                if (result) {
                    a++;
                }
            }
            dataMap.put("createSuccess", a);
            dataMap.put("createFail", b);
            userService.importLog(account, dataList.size(), OwnUtil.getImportLogDataMap(dataMap, a, b, finalType), "processRoute", failList);
        })).sheet().headRowNumber(2).doRead();

        if (isBlank.get()) {
            // 空模板导入记录
            userService.importBlankExcel(null, "processRoute");
        }

        return ResponseData.success("请查看导入日志");
    }


    @UserLoginToken
    @ApiOperation(value = "工艺路线导出")
    @RequestMapping(value = "process_route_export", method = RequestMethod.GET)
    public void processRouteExport(HttpServletResponse response) throws IOException {
        List<ProcessRouteExcelModel> exportList = new ArrayList<>();
        List<ProcessRoute> dataList = processRouteService.list();
        AtomicInteger index = new AtomicInteger(1);
        if (!CollectionUtils.isEmpty(dataList)) {
            dataList.forEach(d -> {
                ProcessRouteExcelModel model = new ProcessRouteExcelModel();
                model.setId(index.getAndIncrement());
                model.setCode(d.getCode());
                model.setName(d.getName());
                if (StringUtil.isNotBlank(d.getProcessList())) {
                    List<ProcessRoteProcessVo> list = JSONArray.parseArray(d.getProcessList()).toJavaList(ProcessRoteProcessVo.class);
                    if (!CollectionUtils.isEmpty(list)) {
                        model.setProcessList(list.stream().map(ProcessRoteProcessVo::getName).collect(Collectors.joining(",")));
                    }
                }
                exportList.add(model);
            });
            String fileName = "exportExcel" + System.currentTimeMillis() + ".xlsx";
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            EasyExcel.write(response.getOutputStream()).sheet("工艺路线导出数据").head(ProcessRouteExcelModel.class).doWrite(exportList);
        }
    }


    @UserLoginToken
    @ApiOperation(value = "导入日志")
    @ApiImplicitParam(name = "type", value = "类型:产品/用户/工序/工艺路线/绩效工资  product/user/process/processRoute/wages", required = true, paramType = "type", dataType = "String")
    @RequestMapping(value = "import_log", method = RequestMethod.POST)
    public ResponseData<?> productImportLog(@RequestBody ImportLogVo vo) {
        JSONArray jsonArray = new JSONArray();
        if (vo.getType().equals("product")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:product" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("user")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:user" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("process")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:process" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("processRoute")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:processRoute" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("wages")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:wages" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("workOrder")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:workOrder" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("workReport")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:workReport" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("badProduct")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:badProduct" + ":" + LoginUtil.getLoginUserFactory());
        } else if (vo.getType().equals("BOM")) {
            jsonArray = (JSONArray) RedisUtil.get("excel:import:BOM" + ":" + LoginUtil.getLoginUserFactory());
        }
        List<ExcelImportLog> list = new ArrayList<>();
        if (jsonArray != null && !jsonArray.isEmpty()) {
            list = jsonArray.toJavaList(ExcelImportLog.class);
            if (!CollectionUtils.isEmpty(list) && vo.getStartTime() != null && vo.getEndTime() != null) {
                List<ExcelImportLog> newList = list.stream().filter(f -> TimeUtil.isEffectiveDate(f.getCreateTime(), vo.getStartTime(), vo.getEndTime()))
                        .sorted(Comparator.comparing(ExcelImportLog::getCreateTime).reversed()).collect(Collectors.toList());
                PageInfo pageInfo = PageUtil.getNewPageInfo(vo.getPage(), vo.getLimit(), newList);
                return ResponseData.success(pageInfo);
            }
            if (!CollectionUtils.isEmpty(list)) {
                list = list.stream().sorted(Comparator.comparing(ExcelImportLog::getCreateTime).reversed()).collect(Collectors.toList());
            }
            PageInfo pageInfo = PageUtil.getNewPageInfo(vo.getPage(), vo.getLimit(), list);
            return ResponseData.success(pageInfo);
        }
        return ResponseData.fail(200, "暂无数据");
    }


    @UserLoginToken
    @ApiOperation(value = "绩效工资配置列表")
    @RequestMapping(value = "wages_list", method = RequestMethod.POST)
    public ResponseData<?> wagesList(@RequestBody WagesListVo vo) {
        List<MatchingRule> mrList = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 1));
        List<Wages> wagesList = wagesService.list(new QueryWrapper<Wages>().eq("del_flag", 1).orderByDesc("id"));
        if (!CollectionUtils.isEmpty(mrList)) {
            List<Wages> newWages = new ArrayList<>();
            if (!CollectionUtils.isEmpty(wagesList)) {
                for (Wages d : wagesList) {
                    if (d.getCreateId() != null) {
                        User u = userService.getById(d.getCreateId());
                        d.setCreateName(u.getName());
                    }
                    if (StringUtil.isNotBlank(d.getOther())) {
                        d.setMap(JSONObject.parseObject(d.getOther()));
                    }
                    if (vo.getParams() != null && !vo.getParams().isEmpty() && StringUtil.isNotBlank(d.getOther())) {
                        int a = (int) vo.getParams().keySet().stream().filter(k -> vo.getParams().get(k).equals(d.getMap().get(k) == null ? "" : d.getMap().get(k))).count();
                        if (a == vo.getParams().size()) {
                            newWages.add(d);
                        }
                    } else if (vo.getParams().isEmpty()) {
                        newWages.add(d);
                    }
                }
            }
            PageInfo pageInfo = PageUtil.getNewPageInfo(vo.getPage(), vo.getLimit(), newWages);
            return ResponseData.success(pageInfo);
        }
        PageInfo pageInfo = PageUtil.getNewPageInfo(vo.getPage(), vo.getLimit(), wagesList);
        return ResponseData.success(pageInfo);
    }


    @UserLoginToken
    @ApiOperation(value = "绩效工资配置操作")
    @RequestMapping(value = "wages_handle", method = RequestMethod.POST)
    public ResponseData<?> wagesHandle(@RequestBody Wages vo) {
        if (vo.getId() != null) {
            vo.setUpdateTime(new Date());
        }
        if (vo.getMap() != null && !vo.getMap().isEmpty()) {
            vo.setOther(JSONObject.parseObject(JSON.toJSONString(vo.getMap())).toJSONString());
        }
        vo.setCreateId(LoginUtil.getLoginUserId());
        vo.setCreateTime(new Date());
        vo.setUpdateTime(new Date());
        wagesService.saveOrUpdate(vo);
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资删除")
    @RequestMapping(value = "wages_del", method = RequestMethod.POST)
    public ResponseData<?> wagesDel(@RequestBody IdVo vo) {
        if (vo.getId() == 0) {
            List<Wages> list = wagesService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Integer> ids = list.stream().map(Wages::getId).collect(Collectors.toList());
                wagesService.removeByIds(ids);
            }
        } else {
            wagesService.removeById(vo.getId());
        }
        return ResponseData.success("success");
    }

    /**
     * 创建时间 更新时间 创建人可不填
     *
     * @param file
     * @return
     * @throws IOException
     */
    @UserLoginToken
    @ApiOperation(value = "绩效工资配置导入")
    @RequestMapping(value = "wages_import", method = RequestMethod.POST)
    public ResponseData<?> wagesImport(MultipartFile file) throws Exception {
        String account = LoginUtil.getLoginAccount();
        // 下标元素名称映射
        Map<Integer, String> indexColumnMap = new HashMap<>();
        List<ColumnsConfigure> regularColumns = customFieldService.wagesRedisHandle();
        List<ColumnsConfigure> newRegularColumns = regularColumns.stream().filter(f -> !"序号".equals(f.getChineseName())).collect(Collectors.toList());
        // 固定列中文名英文名映射
        Map<String, String> regularCnEnMap = new HashMap<>(newRegularColumns.size());
        newRegularColumns.forEach(i -> regularCnEnMap.put(i.getChineseName(), i.getName()));
        //获取自定义字段中英文映射
        Map<String, String> cuCnEnMap = new HashMap<>();
        JSONArray userCustomColumn = (JSONArray) RedisUtil.get("wages_columns:" + LoginUtil.getLoginUserId());
        List<ColumnsConfigure> userColumns = Collections.emptyList();
        if (Objects.nonNull(userCustomColumn) && !userCustomColumn.isEmpty()) {
            userColumns = userCustomColumn.toJavaList(ColumnsConfigure.class);
            userColumns.forEach(i -> cuCnEnMap.put(i.getChineseName(), i.getName()));

        }
        Map<String, List<ColumnsConfigure>> en = userColumns.stream().collect(Collectors.groupingBy(ColumnsConfigure::getName));
        //所有映射
        Map<String, String> allMap = new HashMap<>(regularCnEnMap.size() + cuCnEnMap.size());
        allMap.putAll(regularCnEnMap);
        allMap.putAll(cuCnEnMap);

        //整合好的数据
        List<Map<String, Object>> conformData = new ArrayList<>();
        try (InputStream excelStream = file.getInputStream()) {
            ExcelReaderBuilder read = EasyExcel.read(excelStream);
            read.registerReadListener(new PageReadListener<>(i -> {
                List<Map> collect = i.stream().map(d -> d instanceof Map ? ((LinkedHashMap) d) : Collections.emptyMap()).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    String firstColumn = collect.get(0).getOrDefault(0, "").toString();
                    if (!"工序名称".equals(firstColumn)) {
                        throw new LoginException("500", "模板不匹配");
                    }
                }
                collect.forEach(d -> {
                    Map<String, Object> lineData = new HashMap<>();
                    if (indexColumnMap.isEmpty()) {
                        d.forEach((k, v) -> {
                            if (Objects.nonNull(v)) {
                                indexColumnMap.put(Integer.parseInt(k.toString()), allMap.getOrDefault(v.toString(), null));
                            }
                        });
                    } else {
                        d.forEach((k, v) -> lineData.put(indexColumnMap.get(k), v));
                    }
                    if (!lineData.isEmpty()) {
                        conformData.add(lineData);
                    }
                });
            }));
            read.doReadAll();
        } catch (Exception e) {
            if (e instanceof LoginException) {
                throw e;
            } else {
                e.printStackTrace();
            }
        }
        //整合成bean导入
        List<Wages> finalData = new ArrayList<>();
        conformData.forEach(i -> {
            Map<String, Object> otherMap = new HashMap<>();
            Wages wages = new Wages();
            BeanUtil.fillBeanWithMap(i, wages, true);
            i.forEach((k, v) -> {
                if (Objects.nonNull(en.get(k))) {
                    otherMap.put(k, v);
                }
            });
            otherMap.computeIfPresent("pricing", (k, v) -> "计件".equals(v.toString()) ? 0 : 1);
            wages.setOther(JSONUtil.toJsonStr(otherMap));
            finalData.add(wages);
        });
        wagesService.saveBatch(finalData);
        Map<String, Integer> dataMap = new HashMap<>(2);
        dataMap.put("createSuccess", finalData.size());
        dataMap.put("createFail", 0);
        userService.importLog(account, finalData.size(), dataMap, "wages", null);
        return ResponseData.success("请查看导入日志");

//        EasyExcel.read(file.getInputStream(), WagesExcelImport.class, new PageReadListener<WagesExcelImport>(dataList -> {
//            if (!CollectionUtils.isEmpty(dataList)) {
//                Map<String, Integer> dataMap = new HashMap<>();
//                List<Map<String, String>> failList = new ArrayList<>();
//                Map<String, String> failMap = new HashMap<>();
//                Integer a = 0;
//                Integer b = 0;
//                for (WagesExcelImport d : dataList) {
//                    Product product = productService.getOne(new QueryWrapper<Product>().eq("code", d.getProductCode()));
//                    if (product != null) {
//                        Wages wage = wagesService.getOne(new QueryWrapper<Wages>().eq("product_code", product.getCode()));
////                        wage.setProductCode(d.getProductCode());
////                        wage.setProductName(d.getProductName());
////                        wage.setProductSpecification(d.getProductSpecification());
////                        if (StringUtil.isNotBlank(d.getPricing())) {
////                            if (d.getPricing().equals("计件")) {
////                                wage.setPricing(0);
////                            } else if (d.getPricing().equals("计时")) {
////                                wage.setPricing(1);
////                            }
////                        }
////                        Processes processes = processesService.getOne(new QueryWrapper<Processes>().eq("name", d.getProcessName()));
////                        if (processes != null) {
////                            wage.setProcessName(processes.getName());
////                            wage.setProcessId(processes.getId());
////                        }
//                        wage.setUnitPrice(d.getUnitPrice());
//                        wage.setOutput(d.getOutput());
//                        wage.setWorkingHours(d.getWorkingHours());
//                        wage.setCreateTime(new Date());
//                        wage.setUpdateTime(new Date());
//                        wage.setCreateId(LoginUtil.getLoginUserId());
//                        boolean b1 = wagesService.updateById(wage);
//                        if (b1) {
//                            a++;
//                        }
//                    } else {
//                        failMap.put("失败原因", "产品不存在");
//                        failMap.put("产品编号", d.getProductCode());
//                        failMap.put("产品名称", d.getProductName());
//                        failMap.put("计价方式", d.getPricing());
//                        failMap.put("工资单价", d.getUnitPrice().toString());
//                        failList.add(failMap);
//                        b++;
//                    }
//                }
//                dataMap.put("createSuccess", a);
//                dataMap.put("createFail", b);
//                userService.importLog(account, dataList.size(), dataMap, "wages", failList);
//            }
//        })).sheet().headRowNumber(2).doRead();
//        return ResponseData.success("请查看导入日志");
    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资导出")
    @RequestMapping(value = "wages_export", method = RequestMethod.GET)
    public void wagesExport(HttpServletResponse response) throws IOException {
        List<WagesExcelModel> exportList = new ArrayList<>();
        List<Wages> dataList = wagesService.list();
        if (!CollectionUtils.isEmpty(dataList)) {
            AtomicInteger index = new AtomicInteger(1);
            dataList.forEach(d -> {
                WagesExcelModel wem = new WagesExcelModel();
                BeanUtils.copyProperties(d, wem);
                User u = userService.getById(d.getCreateId());
                wem.setCreateName(u.getName());
//                if (d.getPricing() == 0) {
//                    wem.setPricing("计件");
//                } else if (d.getPricing() == 1) {
//                    wem.setPricing("计时");
//                }
                wem.setCreateTime(TimeUtil.getDateString(d.getCreateTime(), TimeUtil.DEFAULT_DATE_FORMAT));
                wem.setUpdateTime(TimeUtil.getDateString(d.getUpdateTime(), TimeUtil.DEFAULT_DATE_FORMAT));
                wem.setId(index.getAndIncrement());
                exportList.add(wem);
            });
            String fileName = "exportExcel" + System.currentTimeMillis() + ".xlsx";
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            EasyExcel.write(response.getOutputStream()).registerWriteHandler(new CustomCellWriteHandler()).sheet("绩效工资导出数据").head(WagesExcelModel.class).doWrite(exportList);
        }
    }


    @ApiOperation(value = "导入模版")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type",
                    value = "类型：user/product/workOrder/process/processRoute/wages/workReport 用户/产品/工单/工序/工艺路线/绩效工资配置/报工")
    })

    @UserLoginToken
    @RequestMapping(value = "import_model", method = RequestMethod.GET)
    public void importModel(HttpServletResponse response, String type) throws Exception {
        File file = null;
        String template = "";
        String fileName = "";
        boolean flag = false;
        if (type.equals("user")) {
            file = new File( excelTemplatePath.concat("导入用户模版.xlsx"));
        } else if ("device".equals(type)) {
            file = new File(excelTemplatePath.concat("设备导入模板.xlsx"));
        } else if (type.equals("product")) {
            template = excelTemplatePath.concat("产品导入模版.xlsx");
            fileName = "产品导入模版";
        } else if (type.equals("workOrder")) {
            template = excelTemplatePath.concat("导入工单模版.xlsx");
//            template = "/Users/fff/Downloads/excel/导入工单模版.xlsx";
            fileName = "导入工单模版";
        } else if (type.equals("processes")) {
            template = excelTemplatePath.concat("导入工序模版.xlsx");
//            template = "/Users/fff/Downloads/excel/导入工序模版.xlsx";
            fileName = "导入工序模版";
        } else if (type.equals("processRoute")) {
            file = new File( excelTemplatePath.concat("导入工艺路线模版.xlsx"));
        } else if (type.equals("wages")) {
            template = excelTemplatePath.concat("导入绩效工资配置模版.xlsx");
            fileName = "导入绩效工资配置模版";
        } else if (type.equals("workReport")) {
            template = excelTemplatePath.concat("导入报工模版.xlsx");
//            template = "/Users/fff/Downloads/excel/导入报工模版.xlsx";
            fileName = "导入报工模版";
        } else if (type.equals("printWorkOrderList")) {
            file = new File( printTemplatePath.concat("工单列表.xlsx"));
        } else if (type.equals("printWorkOrderCard")) {
            file = new File( printTemplatePath.concat("工单流转卡.xlsx"));
        } else if (type.equals("printWorkOrderQr")) {
            file = new File(printTemplatePath.concat("工单二维码.xlsx"));
        } else if (type.equals("badProduct")) {
            file = new File(excelTemplatePath.concat("导入不良品项模板.xlsx"));
        } else if (type.equals("stockMsg")) {
            template = excelTemplatePath.concat("导入产品明细模版.xlsx");
            fileName = "导入产品明细模版";
        } else if (type.equals("stockProduct")) {
            template = excelTemplatePath.concat("导入产品明细模版.xlsx");
            fileName = "导入产品明细模版";
            flag = true;
        } else if (type.equals("BOM")) {
            template =  excelTemplatePath.concat("导入物料清单明细模板.xlsx");
            fileName = "导入物料清单明细模板";
            flag = true;
        }

        List<List<String>> header = new ArrayList<>();

        if ("salesImportModel".equals(type)) {
            fileName = "导入产品明细模板";
            template = excelTemplatePath.concat("销售订单导入产品明细模版.xlsx");

            //获取工单自定义字段
            ColumnUtils columnUtils = new ColumnUtils(customFieldService, "workOrder");
            // 产品固有字段
            List<String> excludeNames = Arrays.asList("产品属性", "单位", "单位用量", "状态", "生产进度", "", "不良品数", "序号", "工单编号", "完成数");
            List<String> columns = ColumnUtils.BASE_COLUMN_CN_LIST.get("formInProductImport").stream().filter(i -> !CollectionUtils.contains(excludeNames.iterator(), i)).collect(Collectors.toList());
            columnUtils.getCustomFieldList().forEach(i -> {
                if (!i.getChineseName().contains("附件") && !i.getChineseName().contains("图片")) {
                    columns.add(i.getChineseName());
                }
            });
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
            columns.forEach(i -> header.add(Collections.singletonList(i)));
            EasyExcel.write(response.getOutputStream()).withTemplate(template)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet(0).relativeHeadRowIndex(0).head(header).doWrite((Collection<?>) null);
        }

        if (file != null) {
            OwnUtil.fileToResponse(file, response);
        } else if (StringUtil.isNotBlank(template)) {
            String finalType = type;
            if (type.equals("wages")) {
                List<ColumnsConfigure> configureList = customFieldService.wagesRedisHandle();
                configureList.forEach(c -> {
                    if (!c.getChineseName().equals("序号")) {
                        List<String> header1 = new ArrayList<>();
                        header1.add(c.getChineseName());
                        header.add(header1);
                    }
                });
            } else {
                List<ColumnsConfigure> list = customFieldService.handleImportDefault(finalType);
                if (flag) {
                    type = "stockMsg";
                }
                if (list != null && !CollectionUtils.isEmpty(list)) {
                    QueryWrapper<CustomField> ne = new QueryWrapper<CustomField>().eq("field_ascription", type).ne("field_type", "picture")
                            .ne("field_type", "upload").ne(type.equals("stockMsg"), "field_type", "relevanceProp");
                    List<CustomField> customFields = customFieldService.list(ne);
                    if (Objects.nonNull(customFields) && !customFields.isEmpty()) {
                        CustomFieldService.handleReturnList(list, customFields);
                    }
                    list.forEach(l -> {
                        header.add(Collections.singletonList(l.getChineseName()));
                    });
                }
            }
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
            EasyExcel.write(response.getOutputStream()).withTemplate(template)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .sheet(0).relativeHeadRowIndex(0).head(header).doWrite(Collections.emptyList());
        }

    }

    @UserLoginToken
    @ApiOperation(value = "不良品列表for下拉框")
    @RequestMapping(value = "bp_other", method = RequestMethod.POST)
    public ResponseData<?> bpOther(@RequestBody NormalVo vo) {
        List<BadProduct> list = badProductService.list(new QueryWrapper<BadProduct>().like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName()));
        return ResponseData.success(list);
    }

    @UserLoginToken
    @ApiOperation(value = "工艺路线for下拉框")
    @RequestMapping(value = "pr_other", method = RequestMethod.POST)
    public ResponseData<?> prOther(@RequestBody NormalVo vo) {
        List<ProcessRoute> prList = processRouteService.list(new QueryWrapper<ProcessRoute>()
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName()));
        return ResponseData.success(prList);
    }

    @UserLoginToken
    @ApiOperation(value = "产品for下拉框")
    @RequestMapping(value = "p_other", method = RequestMethod.POST)
    public ResponseData<?> pOther(@RequestBody NormalVo vo) {
        List<Product> list = productService.list(new QueryWrapper<Product>()
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode()).eq("del_flag", 0));
        List<Integer> unitIds = new ArrayList<>();
        List<Integer> processRouteIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(i -> {
                if (Objects.nonNull(i.getUnitId())) {
                    unitIds.add(i.getUnitId());
                }
                if (Objects.nonNull(i.getProcessRouteId())) {
                    processRouteIds.add(i.getProcessRouteId());
                }
                if (Objects.nonNull(i.getAttribute())) {
                    switch (i.getAttribute()) {
                        case 0:
                            i.setAttributeName("自制");
                            break;
                        case 1:
                            i.setAttributeName("外购");
                            break;
                        default:
                            i.setAttributeName("委外");
                    }
                }
            });
        }
        Map<Integer, String> unitIdNameMap = new HashMap<>(unitIds.size());
        Map<Integer, String> routeIdNameMap = new HashMap<>(processRouteIds.size());
        if (!CollectionUtils.isEmpty(unitIds)) {
            unitService.listByIds(unitIds).forEach(i -> unitIdNameMap.put(i.getId(), i.getName()));
        }
        if (!CollectionUtils.isEmpty(processRouteIds)) {
            processRouteService.listByIds(processRouteIds).forEach(i -> routeIdNameMap.put(i.getId(), i.getName()));
        }
        list.forEach(i -> {
            if (Objects.nonNull(i.getUnitId())) {
                i.setUnitName(unitIdNameMap.get(i.getUnitId()));
            }
            if (Objects.nonNull(i.getProcessRouteId())) {
                i.setProcessRouteName(routeIdNameMap.get(i.getProcessRouteId()));
            }
        });
        return ResponseData.success(list);
    }

    @UserLoginToken
    @ApiOperation(value = "工序for下拉框")
    @RequestMapping(value = "process_other", method = RequestMethod.POST)
    public ResponseData<?> processOther(@RequestBody NormalVo vo) {
        List<Processes> list = processesService.list(new QueryWrapper<Processes>()
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode()));
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(d -> {
                if (StringUtil.isNotBlank(d.getPermissions())) {
                    List<String> lista = Arrays.asList(d.getPermissions().split(","));
                    List<User> ul = userService.listByIds(lista);
                    d.setPermissionsName(ul.stream().map(User::getName).collect(Collectors.joining(",")));
                }
                if (StringUtil.isNotBlank(d.getBadProduct())) {
                    List<String> lista = Arrays.asList(d.getBadProduct().split(","));
                    List<BadProduct> bl = badProductService.listByIds(lista);
                    d.setBadProductName(bl.stream().map(BadProduct::getName).collect(Collectors.joining(",")));
                }
            });
        }
        return ResponseData.success(list);
    }

    @UserLoginToken
    @ApiOperation(value = "单位for下拉框")
    @RequestMapping(value = "unit_other", method = RequestMethod.POST)
    public ResponseData<?> unitOther(@RequestBody NormalVo vo) {
        List<Unit> list = unitService.list(new QueryWrapper<Unit>().like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode()));
        return ResponseData.success(list);
    }

    @UserLoginToken
    @ApiOperation(value = "部门for下拉框")
    @RequestMapping(value = "dep_other", method = RequestMethod.POST)
    public ResponseData<?> depOther(@RequestBody NormalVo vo) {
        List<Departments> list = departmentsService.list(new QueryWrapper<Departments>().like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .like(StringUtil.isNotBlank(vo.getCode()), "code", vo.getCode()).eq("del_flag", 0));
        return ResponseData.success(list);
    }


    @UserLoginToken
    @ApiOperation(value = "产品定义详情")
    @RequestMapping(value = "product_detail", method = RequestMethod.POST)
    public ResponseData<?> productDetail(@RequestBody IdVo vo) {
        Product product = productService.getById(vo.getId());
        if (product != null) {
            ProductDataHandle(product);
            if (StringUtil.isNotBlank(product.getOther())) {
                product.setCustomFieldVos(customFieldService.handleCustomFieldForList(product.getOther()));
            }
            int attribute = Optional.ofNullable(product.getAttribute()).orElse(0);
            product.setAttributeName(attribute == 0 ? "自制" : (attribute == 1 ? "外购" : "委外"));
        }
        return ResponseData.success(product);
    }

    private void ProductDataHandle(Product product) {
        if (product.getProcessRouteId() != null) {
            ProcessRoute pr = processRouteService.getById(product.getProcessRouteId());
            if (pr != null) {
                product.setProcessRouteName(pr.getName());
            }
        }
        if (product.getUnitId() != null) {
            Unit unit = unitService.getById(product.getUnitId());
            if (unit != null) {
                product.setUnitName(unit.getName());
            }
        }
    }

    @UserLoginToken
    @ApiOperation(value = "工序详情")
    @RequestMapping(value = "process_detail", method = RequestMethod.POST)
    public ResponseData<?> processDetail(@RequestBody IdVo vo) {
        Processes process = processesService.getById(vo.getId());
        ProcessesDataHandle(process, badProductService, userService);
        if (StringUtil.isNotBlank(process.getOther())) {
            process.setCustomFieldVos(customFieldService.handleCustomFieldForList(process.getOther()));
        }
        if (StringUtil.isNotBlank(process.getCollectionData())) {
            process.setVos(JSONArray.parseArray(process.getCollectionData()).toJavaList(CollectionDataVo.class));
        }
        return ResponseData.success(process);

    }

    public static void ProcessesDataHandle(Processes process, BadProductService badProductService, UserService userService) {
        if (StringUtil.isNotBlank(process.getBadProduct())) {
            List<String> list = Arrays.asList(process.getBadProduct().split(","));
            List<BadProduct> bl = badProductService.listByIds(list);
            process.setBadProductName(bl.stream().map(BadProduct::getName).collect(Collectors.joining(",")));
        }
        if (StringUtil.isBlank(process.getPermissionsName())) {
            process.setPermissionsName("所有人");
        }
        if (StringUtil.isBlank(process.getPermissions())) {
            List<User> uL = userService.list(new QueryWrapper<User>().eq("state", 0).eq("factory_id", LoginUtil.getLoginUserFactory()));
            process.setPermissions(uL.stream().map(u -> u.getId()).map(u1 -> u1 + "").collect(Collectors.joining(",")));
        }
    }

    @UserLoginToken
    @ApiOperation(value = "工艺路线详情")
    @RequestMapping(value = "process_route_detail", method = RequestMethod.POST)
    public ResponseData<?> processRouteDetail(@RequestBody IdVo vo) {
        ProcessRoute processRoute = processRouteService.getById(vo.getId());
        return ResponseData.success(processRoute);


    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资配置详情")
    @RequestMapping(value = "wages_detail", method = RequestMethod.POST)
    public ResponseData<?> wagesDetail(@RequestBody IdVo vo) {
        Wages wages = wagesService.getById(vo.getId());
        if (StringUtil.isNotBlank(wages.getOther())) {
            wages.setMap(JSONObject.parseObject(wages.getOther()));
        }
        return ResponseData.success(wages);
    }


    @UserLoginToken
    @ApiOperation(value = "字典")
    @RequestMapping(value = "dict", method = RequestMethod.GET)
    public ResponseData<?> dict() {
        List<Dict> dictList = dictService.list();
        return ResponseData.success(dictList);
    }

    @UserLoginToken
    @ApiOperation(value = "上传文件")
    @RequestMapping(value = "upload_file", method = RequestMethod.POST)
    public ResponseData<?> uploadFile(MultipartFile file) {
        String url = FileUtil.uploadFile(file, "/service/file/" + TimeUtil.getDateDefaultStringTwo(new Date()) + "/");
        return ResponseData.success(url);
    }

    @UserLoginToken
    @ApiOperation(value = "上传文件下载/删除  download/del")
    @RequestMapping(value = "file_download", method = RequestMethod.GET)
    public void fileDownload(HttpServletResponse response, String path, String type) throws IOException {
        if (type.equals("del")) {
            Arrays.asList(path.split(",")).forEach(s -> {
                File file = new File("/service" + s);
                file.delete();
            });
        } else {
            File file = new File("/service" + path);
            if (file != null) {
                OwnUtil.fileToResponse(file, response);
            }
        }
    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资匹配规则执行中列表")
    @RequestMapping(value = "mpm_rule_list", method = RequestMethod.GET)
    public ResponseData<?> mpmRuleList() {
        List<MatchingRule> list = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 1));
        List<DimensionCombination> dimensionCombinations = dimensionCombinationService.list(new QueryWrapper<DimensionCombination>().eq("state", 1));
        List<DimensionCombination> combinationList = dimensionCombinations.stream().sorted(Comparator.comparing(DimensionCombination::getLevel)).collect(Collectors.toList());
        WagesMatchRuleResp resp = new WagesMatchRuleResp();
        resp.setMatchingRules(list);
        resp.setDimensionCombinations(combinationList);

        return ResponseData.success(resp);
    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资取度维数操作&&绩效工资维度组合操作")
    @RequestMapping(value = "mpm_rule_handle", method = RequestMethod.POST)
    public ResponseData<?> mpmRuleHandle(@RequestBody MatchingRule vo) {
        //取数维度操作
        List<MatchingRule> oldMRs = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 1));
        if (vo.getState() == 1) {
            oldMRs.forEach(o -> {
                matchingRuleService.removeByIds(oldMRs.stream().map(MatchingRule::getId).collect(Collectors.toList()));
            });
            if (vo.getType() == 1) {
//                wagesService.getBaseMapper().removeData();
                List<Wages> wagesList = wagesService.list(new QueryWrapper<Wages>().eq("del_flag", 1));
                if (!CollectionUtils.isEmpty(wagesList)) {
                    wagesList.forEach(w -> {
                        w.setDelFlag(0);
                        wagesService.updateById(w);
                    });
                }
            }
            List<MatchingRule> oldState0 = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 0));
            if (!CollectionUtils.isEmpty(oldState0)) {
                oldState0.forEach(o -> {
                    o.setState(1);
                    matchingRuleService.updateById(o);
                });
            }
        } else {
            List<MatchingRule> oldState0 = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 0));
            if (!CollectionUtils.isEmpty(oldState0)) {
                matchingRuleService.removeByIds(oldState0.stream().map(MatchingRule::getId).collect(Collectors.toList()));
            }
            List<MatchingRule> newMRs = vo.getMatchingRules();
            //新增
            newMRs.forEach(i -> {
                i.setState(vo.getState());
                matchingRuleService.save(i);
            });
        }
        if (vo.getState() == 0) {
            //新的维度组合
            List<DimensionCombination> dimensionCombinations = vo.getDimensionCombinations();
            //旧的维度组合
//            List<DimensionCombination> dimensionCombinationList = dimensionCombinationService.list();
//            List<String> ds = dimensionCombinations.stream().map(DimensionCombination::getCombination).collect(Collectors.toList());
//            List<DimensionCombination> delList = dimensionCombinationList.stream().filter(item -> !ds.contains(item.getCombination())).collect(Collectors.toList());
            //删除
//            dimensionCombinationList.forEach(m -> {
//                dimensionCombinationService.removeById(m.getId());
//            });
//            List<String> dcs = dimensionCombinationList.stream().map(DimensionCombination::getCombination).collect(Collectors.toList());
//            List<DimensionCombination> addList = dimensionCombinations.stream().filter(item -> !dcs.contains(item.getCombination())).collect(Collectors.toList());
            List<DimensionCombination> dcList = dimensionCombinationService.list(new QueryWrapper<DimensionCombination>().eq("state", 0));
            if (!CollectionUtils.isEmpty(dcList)) {
                dimensionCombinationService.removeByIds(dcList.stream().map(DimensionCombination::getId).collect(Collectors.toList()));
            }
            //添加
            dimensionCombinations.forEach(m -> {
                m.setState(0);
                dimensionCombinationService.save(m);
            });
//            vo.getDimensionCombinations().forEach(d -> {
//                dimensionCombinationService.update(d, new QueryWrapper<DimensionCombination>().eq("combination", d.getCombination()));
//            });
        } else {
            //旧的维度组合
            List<DimensionCombination> oldDCs = dimensionCombinationService.list(new QueryWrapper<DimensionCombination>().eq("state", 1));
            //新的维度组合
//            List<DimensionCombination> NewDCs = vo.getDimensionCombinations();
//            List<String> ds = NewDCs.stream().map(DimensionCombination::getCombination).collect(Collectors.toList());
//            List<DimensionCombination> delList = oldDCs.stream().filter(item -> !ds.contains(item.getCombination())).collect(Collectors.toList());
//            //删除
//            delList.forEach(m -> dimensionCombinationService.removeById(m.getId()));
            //new
            if (!CollectionUtils.isEmpty(oldDCs)) {
                dimensionCombinationService.removeByIds(oldDCs.stream().map(DimensionCombination::getId).collect(Collectors.toList()));
            }
            List<DimensionCombination> newDCs = dimensionCombinationService.list(new QueryWrapper<DimensionCombination>().eq("state", 0));
            if (!CollectionUtils.isEmpty(newDCs)) {
                newDCs.forEach(n -> {
                    n.setState(1);
                    dimensionCombinationService.updateById(n);
                });
            }
        }
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "绩效工资匹配规则生效")
    @RequestMapping(value = "mpm_rule_take_effect", method = RequestMethod.POST)
    public ResponseData<?> mpmRuleTakeEffect(@RequestBody MatchingRule vo) {

        vo.getMatchingRules().forEach(m -> {
            MatchingRule matchingRule = matchingRuleService.getOne(new QueryWrapper<MatchingRule>().eq("cus_field", m.getCusField()));
            matchingRule.setState(1);
            matchingRuleService.updateById(matchingRule);
        });
        List<MatchingRule> oldMRs = matchingRuleService.list();
        List<MatchingRule> newMRs = vo.getMatchingRules();
        List<String> stringList = newMRs.stream().map(MatchingRule::getAttribute).collect(Collectors.toList());
        List<MatchingRule> delReduce = oldMRs.stream().filter(item -> !stringList.contains(item.getAttribute())).collect(Collectors.toList());
        //删除
        delReduce.forEach(i ->
                matchingRuleService.removeById(i.getId())
        );
        vo.getDimensionCombinations().forEach(d -> {
            DimensionCombination combination = dimensionCombinationService.getOne(new QueryWrapper<DimensionCombination>().eq("combination", d.getCombination()));
            combination.setState(1);
            dimensionCombinationService.updateById(combination);
        });
        //旧的维度组合
        List<DimensionCombination> oldDCs = dimensionCombinationService.list();
        //新的维度组合
        List<DimensionCombination> NewDCs = vo.getDimensionCombinations();
        List<String> ds = NewDCs.stream().map(DimensionCombination::getCombination).collect(Collectors.toList());
        List<DimensionCombination> delList = oldDCs.stream().filter(item -> !ds.contains(item.getCombination())).collect(Collectors.toList());
        //删除
        delList.forEach(m -> dimensionCombinationService.removeById(m.getId()));
        //清除wages表中数据
        wagesService.getBaseMapper().removeData();
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "添加绩效工资取数维度下拉框")
    @RequestMapping(value = "insert_wages_list", method = RequestMethod.GET)
    public ResponseData<?> insertWagesList() {
        List<NameVo> vos = new ArrayList<>();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/test/json.txt")));
            String lin;
            lin = br.readLine();
            JSONArray jsonArray = JSONArray.parseArray(lin);
            vos = jsonArray.toJavaList(NameVo.class);
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (NameVo vo : vos) {
            if (vo.getName().equals("工单")) {
                List<CustomField> fields = customFieldService.list(new QueryWrapper<CustomField>().eq("field_type", "selectRadio")
                        .eq("field_ascription", "workOrder"));
                extracted(vo, fields);
            }
            if (vo.getName().equals("产品")) {
                List<CustomField> fields = customFieldService.list(new QueryWrapper<CustomField>().eq("field_type", "selectRadio")
                        .eq("field_ascription", "product"));
                extracted(vo, fields);
            }
            if (vo.getName().equals("工序")) {
                List<CustomField> fields = customFieldService.list(new QueryWrapper<CustomField>().eq("field_type", "selectRadio")
                        .eq("field_ascription", "processes"));
                extracted(vo, fields);
            }
            if (vo.getName().equals("报工")) {
                List<CustomField> fields = customFieldService.list(new QueryWrapper<CustomField>().eq("field_type", "selectRadio")
                        .eq("field_ascription", "workReport"));
                extracted(vo, fields);
            }
            if (vo.getName().equals("用户")) {
                List<CustomField> fields = customFieldService.list(new QueryWrapper<CustomField>().eq("field_type", "selectRadio")
                        .eq("field_ascription", "user"));
                extracted(vo, fields);
            }
        }
        return ResponseData.success(vos);
    }

    private void extracted(NameVo vo, List<CustomField> fields) {
        List<NameVo> newList = new ArrayList<>();
        fields.forEach(f -> {
            NameVo nameVo = new NameVo();
            nameVo.setName(f.getChineseName());
            nameVo.setCusField(String.valueOf(f.getId()));
            newList.add(nameVo);
        });
        if (!CollectionUtils.isEmpty(vo.getListDown())) {
            vo.getListDown().addAll(newList);
        } else {
            vo.setListDown(newList);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "添加绩效工资配置页属性展示")
    @RequestMapping(value = "resp_show", method = RequestMethod.GET)
    public ResponseData<?> respShow() {
        List<MatchingRule> list = matchingRuleService.list(new QueryWrapper<MatchingRule>().eq("state", 1));
        if (!CollectionUtils.isEmpty(list)) {
            List<MatchingRule> newList = new ArrayList<>();
            list.forEach(m -> {
                CustomField cus = customFieldService.getById(m.getCusField());
                if (cus != null) {
                    m.setFieldId(cus.getId());
                    m.setFieldType(cus.getFieldType());
                    m.setCustomFieldMess(cus);
                    m.setName(m.getCusField());
                } else {
                    m.setFieldType(m.getAttribute());
                    m.setName(m.getCusField());
                    List<String> stringList = getList(m.getAttribute());
                    m.setList(stringList);
                }
                newList.add(m);
            });
            return ResponseData.success(newList);
        }
        return ResponseData.success(Collections.emptyList());
    }

    private List<String> getList(String name) {
        List<Product> products = productService.list(new QueryWrapper<Product>().eq("del_flag", 0));
        if ("产品编号".equals(name)) {
            List<String> collect = products.stream().map(p -> p.getCode()).collect(Collectors.toList());
            return collect;
        } else if ("产品名称".equals(name)) {
            List<String> collect = products.stream().map(p -> p.getName()).collect(Collectors.toList());
            return collect;
        } else if ("工序名称".equals(name)) {
            List<Processes> processes = processesService.list();
            List<String> collect = processes.stream().map(p -> p.getName()).collect(Collectors.toList());
            return collect;
        } else if ("报工单位".equals(name)) {
            List<Unit> units = unitService.list();
            List<String> collect = units.stream().map(u -> u.getName()).collect(Collectors.toList());
            return collect;
        } else if ("计价方式".equals(name)) {
            List<String> collect = new ArrayList<>();
            collect.add("计时");
            collect.add("计件");
            return collect;
        }
        return null;
    }

    //    @H5LoginToken
    @UserLoginToken
    @ApiOperation(value = "工资绩效匹配")
    @RequestMapping(value = "wage_match_test", method = RequestMethod.POST)
    public ResponseData<?> wageMatchTest(@RequestBody WageReportVo vo) throws ExecutionException, InterruptedException {
        Wages wage = wagesService.workReportGetWages(vo);
        return ResponseData.success(wage);
    }

    @UserLoginToken
    @ApiOperation(value = "基础数据批量删除")
    @RequestMapping(value = "base_del", method = RequestMethod.POST)
    public ResponseData<?> baseDel(@RequestBody NormalVo vo) {
        AtomicInteger success = new AtomicInteger();
        AtomicInteger fail = new AtomicInteger();
        if (StringUtil.isNotBlank(vo.getIds()) && vo.getType() != null) {
            switch (vo.getType()) {
                case 0:
                    Arrays.asList(vo.getIds().split(",")).stream().forEach(f -> {
                        List<WorkOrder> list = workOrderService.list(new QueryWrapper<WorkOrder>().eq("product_id", Integer.valueOf(f)));
                        if (CollectionUtils.isEmpty(list)) {
                            Product product = productService.getById(Integer.valueOf(f));
                            product.setDelFlag(1);
                            product.setUpdateTime(new Date());
                            productService.updateById(product);
                            success.getAndIncrement();
                        } else {
                            fail.getAndIncrement();
                        }
                    });
                    break;
                case 1:
                    Arrays.asList(vo.getIds().split(",")).stream().forEach(f -> {
                        List<Product> productList = productService.list(new QueryWrapper<Product>().eq("unit_id", Integer.valueOf(f)));
                        if (CollectionUtils.isEmpty(productList)) {
                            unitService.removeById(Integer.valueOf(f));
                            success.getAndIncrement();
                        } else {
                            fail.getAndIncrement();
                        }
                    });
                    break;
                case 2:
                    Arrays.asList(vo.getIds().split(",")).stream().forEach(f -> {
                        List<Processes> processes = processesService.list(new QueryWrapper<Processes>()
                                .apply("FIND_IN_SET(" + f + ",bad_product)"));
                        if (CollectionUtils.isEmpty(processes)) {
                            badProductService.removeById(Integer.valueOf(f));
                            success.getAndIncrement();
                        } else {
                            fail.getAndIncrement();
                        }
                    });
                    break;
                case 3:
                    Arrays.asList(vo.getIds().split(",")).stream().forEach(f -> {
                        List<WorkOrder> workOrderList = workOrderService.list(new QueryWrapper<WorkOrder>().apply("FIND_IN_SET(" + f + ",process_id)"));
                        if (CollectionUtils.isEmpty(workOrderList)) {
                            processesService.removeById(Integer.valueOf(f));
                            success.getAndIncrement();
                        } else {
                            fail.getAndIncrement();
                        }
                    });
                    break;
                case 4:
                    processRouteService.removeByIds(Arrays.asList(vo.getIds().split(",")));
                    success.set(Arrays.asList(vo.getIds().split(",")).size());
                    break;
                case 5:
                    if (vo.getIds().equals("-1")) {
                        List<Wages> wagesList = wagesService.list();
                        wagesService.removeByIds(wagesList.stream().map(Wages::getId).collect(Collectors.toList()));
                    } else {
                        wagesService.removeByIds(Arrays.asList(vo.getIds().split(",")));
                        success.set(Arrays.asList(vo.getIds().split(",")).size());
                    }
                    break;
            }
        }
        return ResponseData.success("删除成功:" + success.get() + "条" + ",删除失败:" + fail.get() + "条。");
    }


    @UserLoginToken
    @ApiOperation(value = "筛选方案添加/编辑")
    @RequestMapping(value = "screen_plan_handle", method = RequestMethod.POST)
    public ResponseData<?> screenPlanHandle(@RequestBody ScreenPlan vo) {
        if (Objects.isNull(vo.getId())) {
            vo.setCreateUser(LoginUtil.getLoginUserId());
        }
        if (vo.getWorkOrderSearchVo() != null) {
            vo.setScreenCondition(JSON.toJSONStringWithDateFormat(vo.getWorkOrderSearchVo(), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
        } else if (vo.getMissionSearchVo() != null) {
            vo.setScreenCondition(JSON.toJSONStringWithDateFormat(vo.getMissionSearchVo(), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
        } else if (vo.getStockBalanceSearchVo() != null) {
            vo.setScreenCondition(JSON.toJSONStringWithDateFormat(vo.getStockBalanceSearchVo(), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
        } else if (vo.getPrSearchVo() != null) {
            vo.setScreenCondition(JSON.toJSONStringWithDateFormat(vo.getPrSearchVo(), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
        }
//        List<ScreenPlan> screenPlans = screenPlanService.list(new QueryWrapper<ScreenPlan>().eq("type",vo.getType()));
//        if(!CollectionUtils.isEmpty(screenPlans) && screenPlans.size()>=20){
//            return ResponseData.fail(500,"最多只能存在20个筛选方案");
//        }
        // 名称判重
        LambdaQueryWrapper<ScreenPlan> repeatQW = new LambdaQueryWrapper<ScreenPlan>().eq(ScreenPlan::getName, vo.getName()).eq(ScreenPlan::getType, vo.getType()).orderByDesc(ScreenPlan::getId);
        List<ScreenPlan> existOne = screenPlanService.list(repeatQW);
        if (Objects.nonNull(existOne) && !existOne.isEmpty()) {
            vo.setId(existOne.get(0).getId());
        }

        if (StringUtil.isNotBlank(vo.getUserId()) && vo.getUserId().contains("-1")) {
            List<User> userList = userService.list(new QueryWrapper<User>().eq("factory_id", LoginUtil.getLoginUserFactory()).eq("state", 0));
            vo.setUserId("-1," + userList.stream().map(User::getId).map(String::valueOf).collect(Collectors.joining(",")));
        } else {
            vo.setUserIdName(vo.getUserIdName());
//            List<String> strings = new ArrayList<>();
//            if (StringUtil.isNotBlank(vo.getDepId())) {
//                List<Departments> list = departmentsService.listByIds(Arrays.asList(vo.getDepId().split(",")));
//                if (!CollectionUtils.isEmpty(list)) {
//                    list.forEach(l -> {
//                        if (l.getIds() != null && StringUtil.isNotBlank(l.getIds())) {
//                            strings.addAll(Arrays.asList(l.getIds().split(",")));
//
//                        }
//                    });
//                }
//                vo.setDepId(vo.getDepId());
//            }
            if (StringUtil.isNotBlank(vo.getUserId())) {
                List<Departments> list = departmentsService.listByIds(Arrays.asList(vo.getDepId().split(",")));
                vo.setDepId(list.stream().map(i -> i.getId().toString()).collect(Collectors.joining(",")));
            }
            vo.setDepId(vo.getDepId());
            if (StringUtil.isNotBlank(vo.getUserId())) {
                List<User> userList = userService.listByIds(Arrays.asList(vo.getUserId().split(",")));
                vo.setUserId(userList.stream().map(i -> i.getId().toString()).collect(Collectors.joining(",")));
            }
//            vo.setUserId(strings.stream().distinct().collect(Collectors.joining(",")));
//            vo.setUserId(vo.getUserId());
        }
        screenPlanService.saveOrUpdate(vo);
        return ResponseData.success("success");
    }

    @UserLoginToken
    @ApiOperation(value = "筛选方案删除")
    @RequestMapping(value = "sp_del", method = RequestMethod.POST)
    public ResponseData<?> spDel(@RequestBody IdVo vo) {
        screenPlanService.removeById(vo.getId());
        return ResponseData.success("success");
    }


    @Transactional
    @UserLoginToken
    @ApiOperation(value = "清空数据")
    @PostMapping("del_all")
    public ResponseData<?> delAll(@RequestBody NormalVo vo) {
        Integer userId = LoginUtil.getLoginUserId();
        User u = userService.getById(userId);
        if (!StringUtils.hasLength(vo.getPassword()) || !MD5Util.verify(vo.getPassword(), u.getPassword())) {
            return ResponseData.fail("密码错误!");
        }
        if (u.getRole().contains("1")) {
            Integer loginUserFactory = LoginUtil.getLoginUserFactory();
//            userService.getBaseMapper().delAll(loginUserFactory);
            userService.delAllData(u.getFactoryId());
            //custom_number
            List<CustomNumber> list = customNumberService.list();
            list.forEach(c -> {
                c.setTime(3);
                c.setNumber(8);
                c.setNowNum(0);
                customNumberService.updateById(c);
            });
            //sop
            List<ProcessSop> processSops = processSopService.list();
            List<Integer> ids = processSops.stream().filter(f -> f.getId() != 1).map(ProcessSop::getId).collect(Collectors.toList());
            processSopService.removeByIds(ids);
            //screen_plan
            //
            //home
            RedisUtil.del("production:yesterday:" + loginUserFactory);
            RedisUtil.del("production:month:" + loginUserFactory);
            RedisUtil.del("production:day:" + loginUserFactory);
            mongoTemplate.getCollectionNames().forEach(i -> mongoTemplate.dropCollection(i));
            //user_menu && user
            List<User> userList = userService.list(new QueryWrapper<User>().eq("factory_id", loginUserFactory).notIn("id", 1, userId));
            if (!CollectionUtils.isEmpty(userList)) {
                List<UserMenu> userMenus = userMenuService.list(new QueryWrapper<UserMenu>().in("user_id", userList.stream().map(User::getId).collect(Collectors.toList())));
                if (!CollectionUtils.isEmpty(userMenus)) {
                    userMenuService.removeByIds(userMenus.stream().map(UserMenu::getId).collect(Collectors.toList()));
                }
            }
            userService.removeByIds(userList.stream().map(User::getId).collect(Collectors.toList()));
            return ResponseData.success("success");

        }
        return ResponseData.fail(500, "权限不足");
    }

    @UserLoginToken
    @ApiOperation(value = "不良品项导入")
    @RequestMapping(value = "bad_product_import", method = RequestMethod.POST)
    public ResponseData<?> badProductImport(MultipartFile file, Integer type) throws IOException {
        EasyExcelUtils easyExcelUtils = new EasyExcelUtils(BadProductImportModel.class);
        EasyExcel.read(file.getInputStream(), BadProductImportModel.class, easyExcelUtils).sheet().doRead();
        EasyExcelImportUtils.parseExcelToData(file.getBytes(), 1, "不良品项编号");
        ResponseData<?> rd = easyExcelUtils.getResponseData();
        if (rd.getCode() == 500) {
            return rd;
        }
        if (type == null) {
            type = 0;
        }
        Map<String, Integer> dataMap = new HashMap<>();
        List<Map<String, String>> failList = new ArrayList<>();
        AtomicInteger a = new AtomicInteger();
        AtomicInteger b = new AtomicInteger();
        AtomicInteger c = new AtomicInteger();
        Integer finalType = type;
        EasyExcel.read(file.getInputStream(), BadProductImportModel.class, new PageReadListener<BadProductImportModel>(dataList -> {
            if (!CollectionUtils.isEmpty(dataList)) {
                c.set(dataList.size());
                for (BadProductImportModel d : dataList) {
                    BadProduct badProduct = new BadProduct();
                    Map<String, String> failMap = new HashMap<>();
                    if (StringUtil.isNotBlank(d.getCode())) {
                        BadProduct bp = badProductService.getOne(new QueryWrapper<BadProduct>().eq("code", d.getCode()));
                        if (bp != null && finalType == 1) {
                            badProduct = bp;
                        } else if (bp != null) {
                            failMap.put("失败原因", "不良品项编号已存在");
                            failMap.put("不良品项编号", d.getCode());
                            failMap.put("不良品项名称", d.getName());
                            failList.add(failMap);
                            b.getAndIncrement();
                            continue;
                        } else {
                            badProduct.setCode(d.getCode());
                        }
                    } else {
                        badProduct.setCode(customNumberService.generator(8));
                    }
                    if (StringUtil.isBlank(d.getName())) {
                        failMap.put("失败原因", "不良品项名称不能为空");
                        failMap.put("不良品项编号", d.getCode());
                        failMap.put("不良品项名称", d.getName());
                        failList.add(failMap);
                        b.getAndIncrement();
                        continue;
                    } else {
                        badProduct.setName(d.getName());
                    }
                    badProduct.setCreateTime(new Date());
                    badProduct.setUpdateTime(new Date());
                    badProductService.saveOrUpdate(badProduct);
                    a.getAndIncrement();
                }
            }
        })).sheet().doRead();
        userService.importLog(LoginUtil.getLoginAccount(), c.get(), OwnUtil.getImportLogDataMap(dataMap, a.get(), b.get(), type), "badProduct", failList);
        return ResponseData.success("请查看导入日志");
    }

    @UserLoginToken
    @ApiOperation(value = "不良品项导出")
    @RequestMapping(value = "bad_product_export", method = RequestMethod.GET)
    public void badProductExport(HttpServletResponse response, String ids) throws IOException {
        List<BadProduct> bpList = new ArrayList<>();
        if (StringUtil.isNotBlank(ids)) {
            bpList = badProductService.listByIds(Arrays.asList(ids.split(",")).stream().map(Integer::parseInt).collect(Collectors.toList()));
        } else {
            bpList = badProductService.list();
        }
        for (int i = 0; i < bpList.size(); i++) {
            bpList.get(i).setSerialNum(i + 1);
        }
        if (!CollectionUtils.isEmpty(bpList)) {
            String fileName = "不良品项导出" + System.currentTimeMillis() + ".xlsx";
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            EasyExcel.write(response.getOutputStream()).sheet("不良品项导出数据").head(BadProduct.class).doWrite(bpList);
        }
    }

    @UserLoginToken
    @ApiOperation(value = "搜索条件状态")
    @RequestMapping(value = "search_condition", method = RequestMethod.POST)
    public ResponseData<?> searchCondition(@RequestBody SearchConditionModel vo) {
        Integer userId = LoginUtil.getLoginUserId();
        String str = OwnUtil.readFileTxt("searchCondition.txt");
        JSONArray jsonArray = JSON.parseArray(str);
        List<SearchConditionModel> allList = jsonArray.toJavaList(SearchConditionModel.class);
        JSONArray jaUser = (JSONArray) RedisUtil.get(vo.getType() + ":searchCondition:" + userId);
        if (StringUtil.isNotBlank(vo.getType())) {
            List<SearchConditionModel.Model> typeModelList = new ArrayList<>();
            List<CustomField> customFieldList = new ArrayList<>();
            QueryWrapper<CustomField> customFieldQW = new QueryWrapper<CustomField>().ne("field_type", "upload").ne("field_type", "relevanceProp").ne("field_type", "picture");
            if ("stockIn".equals(vo.getType()) || "stockOut".equals(vo.getType())) {
                customFieldQW.eq("field_ascription", "stock");
            } else if ("productForm".equals(vo.getType())) {
                customFieldQW.eq("field_ascription", "workReport");
            } else if ("mission".equals(vo.getType())) {
                customFieldQW.eq("field_ascription", "processes");
            } else if ("stockBalance".equals(vo.getType())) {
                customFieldQW.eq("field_ascription", "product");
            } else if ("stockMsg".equals(vo.getType())) {
                customFieldQW.eq("field_ascription", "stock");
            } else {
                customFieldQW.eq("field_ascription", vo.getType());
            }
            customFieldList = customFieldService.list(customFieldQW);
            Map<String, CustomField> customFieldNameDataMap = new HashMap<>(customFieldList.size());
            customFieldList.forEach(i -> customFieldNameDataMap.put(i.getChineseName(), i));
            if (!CollectionUtils.isEmpty(vo.getModelList())) {
                vo.getModelList().forEach(i -> {
                    CustomField customField = customFieldNameDataMap.get(i.getName());
                    if (Objects.nonNull(customField)) {
                        i.setCustomFieldMess(JSONObject.parseObject(JSON.toJSONString(customField)));
                    }
                });
                jaUser = JSONArray.parseArray(JSON.toJSONString(vo.getModelList()));
                RedisUtil.set(vo.getType() + ":searchCondition:" + userId, jaUser);
//                return ResponseData.success(vo.getModelList());
            }
            if (jaUser == null) {
                typeModelList = allList.stream().filter(f -> f.getType().equals(vo.getType())).findAny().get().getModelList();
                List<SearchConditionModel.Model> finalTypeModelList = typeModelList;
                if (!CollectionUtils.isEmpty(customFieldList)) {
                    customFieldList.forEach(c -> {
                        SearchConditionModel.Model model = new SearchConditionModel.Model();
                        model.setName(c.getChineseName());
                        model.setFlag(false);
                        model.setCustomFieldMess(JSONObject.parseObject(JSON.toJSONString(c)));
                        finalTypeModelList.add(model);
                    });
                }
                return ResponseData.success(finalTypeModelList);
            } else {
                List<SearchConditionModel.Model> cacheTypeModelList = jaUser.toJavaList(SearchConditionModel.Model.class);
                if (!CollectionUtils.isEmpty(cacheTypeModelList)) {
                    Set<String> existColumnName = cacheTypeModelList.stream().map(SearchConditionModel.Model::getName).collect(Collectors.toSet());
                    for (SearchConditionModel.Model i : cacheTypeModelList) {
                        if (CollectionUtils.isEmpty(i.getCustomFieldMess()) || Objects.nonNull(customFieldNameDataMap.get(i.getName()))) {
                            typeModelList.add(i);
                        }
                    }
                    if (!CollectionUtils.isEmpty(customFieldList)) {
                        for (CustomField i : customFieldList) {
                            if (!existColumnName.contains(i.getChineseName())) {
                                SearchConditionModel.Model model = new SearchConditionModel.Model();
                                model.setName(i.getChineseName());
                                model.setFlag(false);
                                model.setCustomFieldMess(JSONObject.parseObject(JSON.toJSONString(i)));
                                typeModelList.add(model);
                            }
                        }
                    }
                    typeModelList.forEach(t -> {
                        if (t.getCustomFieldMess() != null && !t.getCustomFieldMess().isEmpty()) {
                            CustomField cf = t.getCustomFieldMess().toJavaObject(CustomField.class);
                            if (Objects.nonNull(cf) && cf.getFieldType().equals("relevanceObject") && StringUtil.isNotBlank(cf.getBusinessObject())) {
                                Map<Integer, String> map = new HashMap<>();
                                switch (cf.getBusinessObject()) {
                                    case "product":
                                        List<Product> list = productService.list(new QueryWrapper<Product>().eq("del_flag", 0));
                                        if (!CollectionUtils.isEmpty(list)) {
                                            list.forEach(l -> {
                                                map.put(l.getId(), l.getCode() + " | " + l.getName() + " | " + l.getSpecification());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                    case "processes":
                                        List<Processes> processes = processesService.list();
                                        if (!CollectionUtils.isEmpty(processes)) {
                                            processes.forEach(l -> {
                                                map.put(l.getId(), l.getCode() + " | " + l.getName());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                    case "unit":
                                        List<Unit> units = unitService.list();
                                        if (!CollectionUtils.isEmpty(units)) {
                                            units.forEach(l -> {
                                                map.put(l.getId(), l.getName());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                    case "badProduct":
                                        List<BadProduct> badProductList = badProductService.list();
                                        if (!CollectionUtils.isEmpty(badProductList)) {
                                            badProductList.forEach(l -> {
                                                map.put(l.getId(), l.getCode() + " | " + l.getName());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                    case "processRoute":
                                        List<ProcessRoute> processRoutes = processRouteService.list();
                                        if (!CollectionUtils.isEmpty(processRoutes)) {
                                            processRoutes.forEach(l -> {
                                                map.put(l.getId(), l.getCode() + " | " + l.getName());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                    case "user":
                                        List<User> userList = userService.list(new QueryWrapper<User>()
                                                .eq("factory_id", LoginUtil.getLoginUserFactory()).eq("state", 0));
                                        if (!CollectionUtils.isEmpty(userList)) {
                                            userList.forEach(l -> {
                                                map.put(l.getId(), l.getName());
                                            });
                                        }
                                        t.setBusinessObject(map);
                                        break;
                                }
                            }
                        }
                    });
                }
            }
            return ResponseData.success(typeModelList);
        }
        return ResponseData.fail(500, "异常");
    }

    @UserLoginToken
    @ApiOperation(value = "报工自定义公式计算数值")
    @PostMapping(value = "calc")
    public ResponseData<?> calc(@RequestBody CalcVo vo) {
        if (!StringUtils.hasLength(vo.getCuColumnName()) || !StringUtils.hasLength(vo.getWorkReportString())) {
            return ResponseData.fail(500, "参数不能为空!");
        }
        CustomField customField = customFieldService.getOne(new LambdaQueryWrapper<CustomField>().eq(CustomField::getChineseName, vo.getCuColumnName()));
        if (Objects.isNull(customField) || !StringUtils.hasLength(customField.getFormula())) {
            return ResponseData.fail(500, "当前自定义公式不存在!");
        }
        customField.setFormula(customField.getFormula().replace("报工.", ""));


        //获取替换后的公式
        RealFormulaVo realFormulaVo = workReportService.getRealFormula(customField.getFormula());
        List<String> columnName = realFormulaVo.getColumnName();
        List<CustomField> customFields = realFormulaVo.getCustomFields();
        String realFormula = realFormulaVo.getRealFormula();

        //计算
        DefaultContext<String, Object> context = new DefaultContext<>();
        cn.hutool.json.JSONObject formData = JSONUtil.parseObj(vo.getWorkReportString());
        try {
            // 自定义表单内容
            List<Map<String, Object>> customFieldVos = (List<Map<String, Object>>) formData.getOrDefault("customFieldVos", Collections.EMPTY_LIST);

            //固有字段不良品和良品
            columnName.forEach(d -> context.put(d, Convert.toBigDecimal(formData.get(d))));
            //自定义字段并去除特殊字符
            customFields.forEach(d -> context.put(d.getChineseName().replace("-", "").replace("——", ""), Convert.toBigDecimal(customFieldVos.stream().filter(
                    f -> d.getId().toString().equals(f.get("customFieldId").toString())).findFirst().orElse(Collections.EMPTY_MAP).getOrDefault("value", 0))));
            Object eval = new ExpressRunner().execute(realFormula, context, null, false, false);
            return ResponseData.success(eval);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseData.fail(200, "无效计算数字");
        }
    }

    @UserLoginToken
    @ApiOperation(value = "查询条件缓存存储")
    @PostMapping(value = "setSearchCache")
    public ResponseData<?> setSearchCache(@RequestBody GetSearchCacheQuery query) {
        query.setCacheId(":".concat(StringUtils.hasLength(query.getCacheId()) ? query.getCacheId() : LoginUtil.getLoginUserId().toString()));
        if (StringUtils.hasLength(query.getCacheName())) {
            String hashKey = (query.getType() == 0 ? CommonConstant.SEARCH_CONDITION_HASH_KEY : CommonConstant.ORDER_CONDITION_HASH_KEY);
            redisTemplate.opsForHash().put(hashKey, query.getCacheName().concat(query.getCacheId()), query.getJsonValue());
        }
        return ResponseData.success("操作成功");

    }

    @UserLoginToken
    @ApiOperation(value = "查询条件缓存取出")
    @PostMapping(value = "getSearchCache")
    public ResponseData<?> getSearchCache(@RequestBody GetSearchCacheQuery query) {
        query.setCacheId(":".concat(StringUtils.hasLength(query.getCacheId()) ? query.getCacheId() : LoginUtil.getLoginUserId().toString()));
        if (StringUtils.hasLength(query.getCacheName())) {
            String hashKey = (query.getType() == 0 ? CommonConstant.SEARCH_CONDITION_HASH_KEY : CommonConstant.ORDER_CONDITION_HASH_KEY);
            Object cacheObject = redisTemplate.opsForHash().get(hashKey, query.getCacheName().concat(query.getCacheId()));
            return ResponseData.success(cacheObject);
        }
        return ResponseData.success(null);
    }

    @UserLoginToken
    @ApiOperation(value = "获取sop采集模板(ids 传工序code)")
    @PostMapping(value = "sopCollectionTemplate")
    public ResponseData<?> sopCollectionTemplate(@RequestBody IdValueQuery vo) {
        ProcessSop sopData = processSopService.sopCollectionTemplate(vo.getIds());
        return ResponseData.success(Objects.nonNull(sopData) ? sopData : new ProcessSop());
    }


}
